﻿using System.Text;

namespace Devonline.Security;

/// <summary>
/// 数据安全服务
/// 提供对数据的加密解密
/// </summary>
public abstract class SecurityService(SecuritySetting securitySetting) : ISecurityService
{
    protected readonly SecuritySetting _securitySetting = securitySetting;

    /// <summary>
    /// 使用已实现的加密算法加密明文数据
    /// </summary>
    /// <param name="data">明文数据</param>
    /// <returns>加密后的数据</returns>
    public abstract Task<byte[]> EncryptAsync(byte[] data);
    /// <summary>
    /// 使用已实现的加密算法解密密文数据
    /// </summary>
    /// <param name="data">密文数据</param>
    /// <returns>解密后的明文数据</returns>
    public abstract Task<byte[]> DecryptAsync(byte[] data);

    /// <summary>
    /// 加密明文文本
    /// 先使用特定字符编码对明文字符串进行编码, 然后使用已实现的加密算法进行加密, 在将结果转换为 Base64 编码的字符串格式输出
    /// </summary>
    /// <param name="plainText">明文文本</param>
    /// <param name="encoding">字符编码, 默认将使用 UTF8</param>
    /// <returns>加密后的密文文本</returns>
    public virtual async Task<string> EncryptAsync(string plainText, Encoding? encoding = default)
    {
        var data = (encoding ?? _securitySetting.Encoding).GetBytes(plainText);
        var encrypted = await EncryptAsync(data);
        return Convert.ToBase64String(encrypted);
    }
    /// <summary>
    /// 解密密文文本
    /// 先将原始密文以 Base64 编码的字符串格式进行解码, 然后使用已实现的加密算法进行解密, 在将结果使用特定字符编码进行编码输出
    /// </summary>
    /// <param name="cipherText">密文文本</param>
    /// <param name="encoding">字符编码, 默认将使用 UTF8</param>
    /// <returns>解密后的明文文本</returns>
    public virtual async Task<string> DecryptAsync(string cipherText, Encoding? encoding = default)
    {
        var data = Convert.FromBase64String(cipherText);
        var decrypted = await DecryptAsync(data);
        return (encoding ?? _securitySetting.Encoding).GetString(decrypted);
    }
}